package com.jilefojing.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.data.manager.response.DCategoryData;
import com.jilefojing.beans.data.manager.response.RCategorySourceData;
import com.jilefojing.beans.data.manager.response.RecommendData;
import com.jilefojing.beans.data.response.base.ResponseData;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.StatusEnumForPublish;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.DCategory;
import com.jilefojing.beans.pojos.RCategorySource;
import com.jilefojing.beans.pojos.enhanced.EnhancedDCategory;
import com.jilefojing.beans.pojos.enhanced.EnhancedEAudio;
import com.jilefojing.beans.pojos.enhanced.EnhancedEVideo;
import com.jilefojing.beans.pojos.enhanced.EnhancedRCategorySource;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.DCategoryQuery;
import com.jilefojing.beans.query.EAudioQuery;
import com.jilefojing.beans.query.EVideoQuery;
import com.jilefojing.beans.query.RCategorySourceQuery;
import com.jilefojing.beans.vo.Order;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.controller.base.BaseController;
import com.jilefojing.controller.convent.CommonConvent;
import com.jilefojing.service.IDCategoryService;
import com.jilefojing.service.IEAudioService;
import com.jilefojing.service.IEVideoService;
import com.jilefojing.service.IRCategorySourceService;
import com.jilefojing.service.ISourceService;
import com.jilefojing.util.Detect;

@Controller
@RequestMapping("category")
public class CategoryController extends BaseController {
	@Autowired
	private ISourceService sourceService;
	@Autowired
	private IDCategoryService dCategoryService;
	@Autowired
	private IRCategorySourceService rCategorySourceService;
	@Autowired
	private IEVideoService eVideoService;
	@Autowired
	private IEAudioService eAudioService;

	@RequestMapping("children-config.html")
	public String toChildrenConfig(long id) {
		return "category/children_config";
	}

	@RequestMapping("add")
	public @ResponseBody ResponseData add(DCategory dCategory, HttpServletRequest request) throws UserContextException {
		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			dCategoryService.add(dCategory, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping("add.html")
	public String toAddPage(Boolean entity, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		if (entity == null || entity) {
			return "category/add";
		}
		return "category/not_entity_add";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	public @ResponseBody ResponseData update(DCategory dCategory, HttpServletRequest request) {
		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			dCategoryService.update(dCategory, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping(value = "delete", method = RequestMethod.POST)
	public @ResponseBody ResponseData delete(@RequestParam("ids[]") ArrayList<Long> ids, HttpServletRequest request) {
		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			boolean entity = Boolean.valueOf(request.getParameter("entity"));

			if (entity) {
				dCategoryService.deleteByIdsForEntity(ids, Boolean.valueOf(request.getParameter("force")), userContext);
			} else {
				dCategoryService.deleteByIdsForNotEntity(ids, userContext);
			}

		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping("list")
	public @ResponseBody Map<String, Object> getList(Boolean entity, Short itemType, String ckey, String like_name, Long parentId, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		int page = Integer.valueOf(request.getParameter("page"));
		int rows = Integer.valueOf(request.getParameter("rows"));

		String sortsStr = request.getParameter("sort");
		String ordersStr = request.getParameter("order");

		Pagination<EnhancedDCategory> pagination = new Pagination<EnhancedDCategory>(page, rows, true);
		if (!Detect.notEmpty(sortsStr)) {
			pagination.addOrder(new Order(DCategory.COLUMN_SORT, Order.ORDER_DESC)).addOrder(new Order(DCategory.COLUMN_UPDATE_TIME, Order.ORDER_DESC))
					.addOrder(new Order(DCategory.COLUMN_C_KEY, Order.ORDER_ASC));
		} else {
			super.addSorts(sortsStr, ordersStr, DCategory.FIELD_SORT, DCategory.COLUMN_SORT, pagination);
			super.addSorts(sortsStr, ordersStr, DCategory.FIELD_UPDATETIME, DCategory.COLUMN_UPDATE_TIME, pagination);
			super.addSorts(sortsStr, ordersStr, DCategory.FIELD_CKEY, DCategory.COLUMN_C_KEY, pagination);
		}

		DCategoryQuery dCategoryQuery = new DCategoryQuery();
		if (itemType != null && itemType > 0) {
			dCategoryQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { ItemTypeEnumForSource.getItemTypeEnumByCode(itemType) }));
		}
		if (Detect.notEmpty(ckey)) {
			dCategoryQuery.setCkeys(Arrays.asList(new String[] { ckey }));
		}
		dCategoryQuery.setEntity(entity);
		if (Detect.notEmpty(like_name)) {
			dCategoryQuery.setLike_name(like_name);
		}
		if (parentId != null && parentId > 0) {
			dCategoryQuery.setParentIds(Arrays.asList(new Long[] { parentId }));
		}

		pagination = dCategoryService.getPagination(dCategoryQuery, pagination, userContext);
		List<DCategoryData> dCategoryDatas = new ArrayList<DCategoryData>();

		Map<String, Object> resultMap = new HashMap<String, Object>();

		resultMap.put("total", pagination.getCount());
		if (Detect.notEmpty(pagination.getItems())) {

			pagination.setItems(dCategoryService.appendEnhancedParentDCategory2EnhancedDCategories(pagination.getItems(), userContext));
			pagination.setItems(dCategoryService.appendEnhancedChildDCategories2EnhancedDCategories(pagination.getItems(), userContext));

			dCategoryDatas = CommonConvent.convent2DCategoryDatas(pagination.getItems());
		}
		resultMap.put("rows", dCategoryDatas);

		return resultMap;
	}

	@RequestMapping("list/top/{itemType}")
	public @ResponseBody List<DCategoryData> getTopList(@PathVariable("itemType") Short itemType, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		ItemTypeEnumForSource itemTypeEnumForSource = null;
		if (itemType != null) {
			itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);
		}

		List<DCategoryData> dCategoryDatas = new ArrayList<DCategoryData>();
		DCategoryData dCategoryData = new DCategoryData();
		dCategoryData.setText("全部分类集合");
		dCategoryData.setCkey("");
		dCategoryData.setSelected(true);
		dCategoryDatas.add(dCategoryData);

		List<EnhancedDCategory> enhancedDCategories = dCategoryService.getEnhancedTopDCategoriesByItemType(itemTypeEnumForSource, userContext);
		if (Detect.notEmpty(enhancedDCategories)) {
			dCategoryDatas.addAll(CommonConvent.convent2DCategoryDatas(enhancedDCategories));
		}
		return dCategoryDatas;
	}

	@RequestMapping("list.html")
	public String toListPage(Boolean entity, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		if (entity == null || entity) {
			return "category/list";
		}
		return "category/not_entity_list";
	}

	@RequestMapping("item/update")
	public @ResponseBody ResponseData updateItem(RCategorySource rCategorySource, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		ResponseData responseData = new ResponseData();
		try {
			rCategorySourceService.update(rCategorySource, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}

		return responseData;
	}

	@RequestMapping("item/add.html")
	public String toAddPage(short itemType, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);

		return "category/" + itemTypeEnumForSource.getItemClass().getSimpleName().toLowerCase() + "_add";
	}

	@RequestMapping("item/delete")
	public @ResponseBody ResponseData deleteItem(long rid, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		ResponseData responseData = new ResponseData();
		rCategorySourceService.deleteById(rid, userContext);

		return responseData;
	}

	@RequestMapping("item/list")
	public @ResponseBody Map<String, Object> getListItems(Short itemType, Short status, String like_title, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		int page = Integer.valueOf(request.getParameter("page"));
		int rows = Integer.valueOf(request.getParameter("rows"));

		String sortsStr = request.getParameter("sort");
		String ordersStr = request.getParameter("order");

		Pagination<EnhancedRCategorySource> pagination = new Pagination<EnhancedRCategorySource>(page, rows, true);
		if (!Detect.notEmpty(sortsStr)) {
			pagination.addOrder(new Order(RCategorySource.COLUMN_SORT, Order.ORDER_DESC)).addOrder(new Order(RCategorySource.COLUMN_UPDATE_TIME, Order.ORDER_DESC));
		} else {
			super.addSorts(sortsStr, ordersStr, RCategorySource.FIELD_SORT, RCategorySource.COLUMN_SORT, pagination);
			super.addSorts(sortsStr, ordersStr, RCategorySource.FIELD_UPDATETIME, RCategorySource.COLUMN_UPDATE_TIME, pagination);
			super.addSorts(sortsStr, ordersStr, RCategorySource.FIELD_HOTSORT, RCategorySource.COLUMN_HOT_SORT, pagination);
		}

		RCategorySourceQuery rCategorySourceQuery = new RCategorySourceQuery();
		if (itemType != null && itemType > 0) {
			ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);
			rCategorySourceQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { itemTypeEnumForSource }));

			if (Detect.notEmpty(like_title)) {
				List<Long> itemIds = this.getItemIdsByLikeTitle(itemTypeEnumForSource, like_title, userContext);
				if (!Detect.notEmpty(itemIds)) {
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.put("total", 0);
					resultMap.put("rows", new ArrayList<RecommendData>());
					return resultMap;
				}
				rCategorySourceQuery.setItemIds(itemIds);
			}

		}
		if (status != null && status > 0) {
			rCategorySourceQuery.setStatuses(Arrays.asList(new StatusEnumForPublish[] { StatusEnumForPublish.getStatusEnumByCode(status) }));
		}

		pagination = rCategorySourceService.getPagination(rCategorySourceQuery, pagination, userContext);

		Map<String, Object> resultMap = new HashMap<String, Object>();

		resultMap.put("total", pagination.getCount());
		List<RCategorySourceData> rCategorySourceDatas = new ArrayList<RCategorySourceData>();
		if (Detect.notEmpty(pagination.getItems())) {
			List<BaseEnhanced> enhancedItems = new ArrayList<BaseEnhanced>();
			for (EnhancedRCategorySource _EnhancedRCategorySource : pagination.getItems()) {
				enhancedItems.add(_EnhancedRCategorySource.getEnhancedItem());
			}
			enhancedItems = sourceService.appendEnhancedParent2EnhancedItems(enhancedItems, userContext);

			rCategorySourceDatas = CommonConvent.convent2RCategorySourceDatas(pagination.getItems());
		}
		resultMap.put("rows", rCategorySourceDatas);

		return resultMap;
	}

	private List<Long> getItemIdsByLikeTitle(ItemTypeEnumForSource itemType, String like_title, UserContext userContext) {
		List<Long> itemIds = new ArrayList<Long>();
		@SuppressWarnings("rawtypes")
		Pagination pagination = null;
		if (itemType == ItemTypeEnumForSource.VIDEO) {
			EVideoQuery eVideoQuery = new EVideoQuery();
			eVideoQuery.setLike_title(like_title);
			pagination = eVideoService.getPagination(eVideoQuery, new Pagination<EnhancedEVideo>(1, Integer.MAX_VALUE, false), userContext);
		} else if (itemType == ItemTypeEnumForSource.AUDIO) {
			EAudioQuery eAudioQuery = new EAudioQuery();
			eAudioQuery.setLike_title(like_title);
			pagination = eAudioService.getPagination(eAudioQuery, new Pagination<EnhancedEAudio>(1, Integer.MAX_VALUE, false), userContext);
		} else {
			throw new IllegalArgumentException("[暂不支持此类型的标题查询]");
		}
		if (Detect.notEmpty(pagination.getItems())) {
			@SuppressWarnings("unchecked")
			List<BaseEnhanced> enhancedItems = (List<BaseEnhanced>) pagination.getItems();
			for (BaseEnhanced _BaseEnhanced : enhancedItems) {
				itemIds.add(_BaseEnhanced.getDynamicId());
			}
		}
		return itemIds;
	}

	@RequestMapping("item/list.html")
	public String toListItemsPage(short itemType, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);

		return "category/" + itemTypeEnumForSource.getItemClass().getSimpleName().toLowerCase() + "_list";
	}

	/**
	 * 获取顶级类型
	 * 
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("top/list/{itemType}")
	public @ResponseBody List<DCategoryData> getCategory(@PathVariable("itemType") short itemType, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		List<EnhancedDCategory> enhancedTopDCategories = dCategoryService.getEnhancedTopDCategoriesByItemType(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), userContext);// 获取顶级分类

		return CommonConvent.convent2DCategoryDatas(enhancedTopDCategories);
	}

	/**
	 * 获取类别--包含指定资源的类别
	 * 
	 * @param itemType
	 * @param itemId
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("get/{id}")
	public @ResponseBody List<DCategoryData> getCategory(@PathVariable("id") long topId, short itemType, long itemId, String like_name, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		Pagination<EnhancedDCategory> pagination = new Pagination<EnhancedDCategory>(1, Integer.MAX_VALUE, false);
		DCategoryQuery dCategoryQuery = new DCategoryQuery();
		dCategoryQuery.setLike_name(like_name);
		dCategoryQuery.setParentIds(Arrays.asList(new Long[] { topId }));
		dCategoryQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { ItemTypeEnumForSource.getItemTypeEnumByCode(itemType) }));
		pagination = dCategoryService.getPagination(dCategoryQuery, pagination, userContext);
		if (!Detect.notEmpty(pagination.getItems())) {
			return new ArrayList<DCategoryData>();
		}

		List<DCategoryData> dCategoryDatas = CommonConvent.convent2DCategoryDatas(pagination.getItems());

		BaseEnhanced enhancedItem = sourceService.getEnhancedItem(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, userContext);

		enhancedItem = sourceService.appendEnhancedDCategories2EnhancedItem(enhancedItem, userContext);
		this.appendChecked((List<EnhancedDCategory>) enhancedItem.get("getEnhancedTypeDCategories"), dCategoryDatas);
		this.appendChecked((List<EnhancedDCategory>) enhancedItem.get("getEnhancedRegionDCategories"), dCategoryDatas);
		this.appendChecked((List<EnhancedDCategory>) enhancedItem.get("getEnhancedChannelDCategories"), dCategoryDatas);
		this.appendChecked((List<EnhancedDCategory>) enhancedItem.get("getEnhancedYoushengshuDCategories"), dCategoryDatas);
		this.appendChecked((List<EnhancedDCategory>) enhancedItem.get("getEnhancedYinyueDCategories"), dCategoryDatas);
		// TODO 可以继续增加 资源类别

		return dCategoryDatas;
	}

	private void appendChecked(List<EnhancedDCategory> enhancedDCategories, List<DCategoryData> dCategoryDatas) {
		if (Detect.notEmpty(enhancedDCategories) && Detect.notEmpty(dCategoryDatas)) {
			for (DCategoryData _child : dCategoryDatas) {
				for (EnhancedDCategory _EnhancedDCategory : enhancedDCategories) {
					if (_child.getId() == _EnhancedDCategory.getId()) {
						_child.setChecked(true);
						break;
					}
				}
			}
		}
	}

	/**
	 * 类别设置
	 * 
	 * @param itemType
	 * @param itemId
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("set")
	public @ResponseBody ResponseData set(short itemType, long itemId, String ckey, @RequestParam("categoryIds[]") ArrayList<Long> categoryIds, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		ResponseData responseData = new ResponseData();

		sourceService.addDCategories(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, ckey, categoryIds, userContext);

		return responseData;
	}

	/**
	 * 类别设置界面
	 * 
	 * @param itemType
	 * @param itemId
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("set.html")
	public String setPage(short itemType, long itemId, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		BaseEnhanced baseEnhanced = sourceService.getEnhancedItem(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, userContext);

		request.setAttribute("itemType", ItemTypeEnumForSource.getItemTypeEnumByCode(itemType));
		request.setAttribute("entity", baseEnhanced);

		return "category/set";
	}
}
